package cn.school.newExam.service.impl;

import cn.school.basics.dao.BaseSubjectDao;
import cn.school.basics.dao.MajorSubjectDao;
import cn.school.basics.entity.MajorSubject;
import cn.school.basics.vo.BaseSubjectVO;
import cn.school.classManage.dao.SchoolClassDao;
import cn.school.classManage.service.SchoolClassService;
import cn.school.classManage.vo.SchoolClassVO;
import cn.school.common.api.CommonResult;
import cn.school.common.exception.ApiException;
import cn.school.common.utils.StringUtils;
import cn.school.common.utils.SysUserUtils;
import cn.school.common.utils.poi.ExcelPoi;
import cn.school.educational.entity.Subject;
import cn.school.educational.service.SubjectService;
import cn.school.newExam.dao.ExamCommentMapper;
import cn.school.newExam.dao.ExamPlanMapper;
import cn.school.newExam.dao.ExamScoreMapper;
import cn.school.newExam.entity.ExamComment;
import cn.school.newExam.entity.ExamPlan;
import cn.school.newExam.entity.ExamScore;
import cn.school.newExam.service.ExamPlanService;
import cn.school.newExam.service.ExamScoreService;
import cn.school.newExam.utils.ExamScoreTable;
import cn.school.newExam.utils.ExcelApi;
import cn.school.student.entity.StudentInfo;
import cn.school.student.service.StudentInfoService;
import cn.school.sys.dao.TermTimeDao;
import cn.school.sys.entity.SysUser;
import cn.school.sys.entity.TermTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Slf4j
@Service
public class ExamScoreServiceImpl extends ServiceImpl<ExamScoreMapper, ExamScore> implements ExamScoreService {

    @Resource
    private ExamScoreMapper examScoreMapper;

    @Resource
    private SchoolClassService schoolClassService;

    @Resource
    private StudentInfoService studentInfoService;

    @Resource
    private SubjectService subjectService;

    @Resource
    private ExamPlanService examPlanService;

    @Resource
    private SchoolClassDao schoolClassDao;

    @Resource
    private BaseSubjectDao baseSubjectDao;

    @Resource
    private MajorSubjectDao majorSubjectDao;

    @Resource
    private TermTimeDao termTimeDao;

    @Resource
    private ExamCommentMapper examCommentMapper;

    @Transactional
    @Override
    public ExamScoreTable initExamScoreTable(ExamScoreTable examScoreTable) {
        List<ExamScore> examScoreList = new ArrayList<>();
        List<StudentInfo> classStu = studentInfoService.findStudentListByClassId(examScoreTable.getClassId());
        SchoolClassVO classInfo = schoolClassService.findClassInfoByClassId(examScoreTable.getClassId());
        Subject subject = subjectService.getSubjectById(examScoreTable.getSubjectId());
        ExamPlan examPlan = examPlanService.getExamPlanById(examScoreTable.getExamPlanId().toString());
        examScoreTable.setExamPlanName(examPlan.getExamName());
        if (classStu != null && classStu.size() > 0) {
            for (StudentInfo studentInfo : classStu) {
                ExamScore examScore = new ExamScore();
                examScore.setExamPlanId(examScoreTable.getExamPlanId().toString());
                examScore.setExamPlanName(examPlan.getExamName());
                examScore.setStudentId(studentInfo.getId().toString());
                examScore.setStudentCode(studentInfo.getStudentId());
                examScore.setStudentName(studentInfo.getName());
                examScore.setClassId(classInfo.getId().toString());
                examScore.setClassName(classInfo.getClassName());
                examScore.setSubjectId(examScoreTable.getSubjectId().toString());
                examScore.setSubjectName(subject.getSubjName());
                if (examScoreTable.getClassId() != null
                        && examScoreTable.getSubjectId() != null
                        && examScoreTable.getExamPlanId() != null) {
                    ExamScore examScore1 = getExamScore(examScoreTable.getExamPlanId().toString(),
                            examScoreTable.getClassId().toString(),
                            examScoreTable.getSubjectId().toString(),
                            studentInfo.getId().toString());
                    if (examScore1 != null) {
                        examScore.setScore(examScore1.getScore());
                    }
                }
                examScoreList.add(examScore);
            }
        }
        examScoreTable.setExamScoreList(examScoreList);
        return examScoreTable;
    }

    @Transactional
    @Override
    public CommonResult scoresRecord(ExamScoreTable examScoreTable) {
        SysUser sysUser = SysUserUtils.getSysUser();
        List<ExamScore> examScoreList = examScoreTable.getExamScoreList();
        for (ExamScore examScore : examScoreList) {
            if (StringUtils.isEmpty(examScore.getScore()) && examScore.getStatus() == 0) {
                return CommonResult.success("500","表单填写不完整");
            }
            examScore.setCreateBy(sysUser.getUsername());
            examScore.setCreateTime(new Date());
        }
        List<ExamScore> examScoreList1 = queryList(examScoreTable);
        for (ExamScore examScore : examScoreList1) {
            removeById(examScore.getId());
        }
        return saveBatch(examScoreList) ? CommonResult.success("200") : CommonResult.failed();
    }

    @Override
    public List<ExamScore> queryList(ExamScoreTable examScoreTable) {
        List<ExamScore> list = examScoreMapper.queryList(examScoreTable);
        return list;
    }

    @Override
    public List<ExamScore> queryList(ExamScore dto) {
        LambdaQueryWrapper<ExamScore> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dto.getStudentId() != null,ExamScore::getStudentId,dto.getStudentId());
        queryWrapper.eq(dto.getExamPlanId() != null,ExamScore::getExamPlanId,dto.getExamPlanId());
        queryWrapper.eq(dto.getClassId() != null,ExamScore::getClassId,dto.getClassId());
        List<ExamScore> examScoreList = this.baseMapper.selectList(queryWrapper);
        return examScoreList;
    }

    @Override
    public int getClassExamScoreCount(String examPlanId, String classId, String subjectId) {
        return examScoreMapper.getClassExamScoreCount(examPlanId, classId, subjectId);
    }

    @Override
    public ExamScore getExamScore(String examPlanId, String classId, String subjectId, String stuId) {
        return examScoreMapper.getExamScore(examPlanId, classId, subjectId, stuId);
    }

//    @Override
//    public boolean importScore(MultipartFile file) {
//        SysUser sysUser = SysUserUtils.getSysUser();
//        List<ExamScore> examScoreList;
//        try {
//            InputStream inputStream = file.getInputStream();
//            ExcelApi<ExamScore> excelApi = new ExcelApi<>(ExamScore.class);
//            examScoreList = excelApi.importExcel(inputStream);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        if(examScoreList == null || examScoreList.size() == 0){
//            return false;
//        }
//        for (ExamScore examScore : examScoreList) {
//            examScore.setCreateBy(sysUser.getUsername());
//            examScore.setCreateTime(new Date());
//        }
//        ExamScoreTable examScoreTable = new ExamScoreTable();
//        examScoreTable.setExamPlanId(Long.parseLong(examScoreList.get(0).getExamPlanId()));
//        examScoreTable.setSubjectId(Long.parseLong(examScoreList.get(0).getSubjectId()));
//        examScoreTable.setClassId(Long.parseLong(examScoreList.get(0).getClassId()));
//        List<ExamScore> examScoreList1 = queryList(examScoreTable);
//        for (ExamScore examScore : examScoreList1) {
//            removeById(examScore.getId());
//        }
//        return saveBatch(examScoreList);
//    }

    @Transactional
    @Override
    public boolean importScore(MultipartFile file) {
        SysUser sysUser = SysUserUtils.getSysUser();
        String tenantId = SysUserUtils.getSysUser().getTenantId();
        List<ExamScore> examScoreList = null;
        try {
            InputStream inputStream = file.getInputStream();
            ExcelApi<ExamScore> excelApi = new ExcelApi<>(ExamScore.class);
            examScoreList = excelApi.importExcel(inputStream);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (examScoreList == null || examScoreList.size() == 0) {
            return false;
        }
        List<ExamScore> examScoreList1 = null;
        List<ExamScore> addList = new ArrayList<>();
        for (ExamScore examScore : examScoreList) {
            //学生
            StudentInfo studentInfo = studentInfoService.getStudentInfo(examScore.getStudentId());
            if(studentInfo == null){
                continue;
            }
            if(!studentInfo.getName().equals(examScore.getStudentName())){
                continue;
            }
            //班级
            LambdaQueryWrapper<SchoolClassVO> classQueryWrapper = new LambdaQueryWrapper<>();
            classQueryWrapper.eq(SchoolClassVO::getClassName,examScore.getClassName());
            classQueryWrapper.eq(SchoolClassVO::getTenantId,tenantId);
            SchoolClassVO classInfo = schoolClassService.getOne(classQueryWrapper);
            if(classInfo == null){
                continue;
            }
            //考试名称
            ExamPlan dto = new ExamPlan();
            dto.setExamName(examScore.getExamPlanName());
            ExamPlan examPlan = examPlanService.queryExamPlan(dto);
            if(examPlan == null){
                continue;
            }
            //科目
            LambdaQueryWrapper<Subject> subjectQueryWrapper = new LambdaQueryWrapper<>();
            subjectQueryWrapper.eq(Subject::getSubjName,examScore.getSubjectName());
            subjectQueryWrapper.eq(Subject::getTenantId,tenantId);
            Subject subject = subjectService.getOne(subjectQueryWrapper);
            if(subject == null){
                continue;
            }

            examScore.setStudentCode(studentInfo.getStudentId());
            examScore.setClassId(classInfo.getId().toString());
            examScore.setExamPlanId(examPlan.getId().toString());
            examScore.setSubjectId(subject.getId().toString());
            examScore.setCreateBy(sysUser.getUsername());
            examScore.setCreateTime(new Date());
            addList.add(examScore);

            if(examScoreList1 == null){
                ExamScoreTable examScoreTable = new ExamScoreTable();
                examScoreTable.setExamPlanId(Long.parseLong(examScore.getExamPlanId()));
                examScoreTable.setSubjectId(Long.parseLong(examScore.getSubjectId()));
                examScoreTable.setClassId(Long.parseLong(examScore.getClassId()));
                examScoreList1 = queryList(examScoreTable);
            }
        }
        if(examScoreList != null && examScoreList1.size() > 0){
            for (ExamScore examScore : examScoreList1) {
                removeById(examScore.getId());
            }
        }
        return saveBatch(addList);
    }

    @Override
    public List<Map<String, Object>> getStudentAllExamScore(Long studentId) {

        List<Map<String, Object>> returnList = new ArrayList<>();
        StudentInfo studentInfo = studentInfoService.getStudentInfo(String.valueOf(studentId));

        if(studentInfo == null){
            log.info("getStudentAllExamScore => 入参学生ID有误");
            return null;
        }
        //学生所在班级
        Long classId = studentInfo.getClassId();
        SchoolClassVO schoolClassVO = schoolClassDao.selectById(classId);
        if(schoolClassVO == null){
            log.info("getStudentAllExamScore => 无法找到学生班级");
            return null;
        }
        //班级所属专业
        String classMajor = schoolClassVO.getClassSubject();
        BaseSubjectVO major = baseSubjectDao.selectById(classMajor);
        if(major == null){
            log.info("getStudentAllExamScore => 无法找到班级所属专业");
            return null;
        }

        //专业下所有科目
        LambdaQueryWrapper<MajorSubject> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MajorSubject::getMajorId,major.getId());
        List<MajorSubject> majorSubjectList = majorSubjectDao.selectList(wrapper);
        if(majorSubjectList == null || majorSubjectList.size() <= 0){
            log.info("getStudentAllExamScore => 当前专业和科目不存在关联关系");
            return null;
        }

        //查询当前专业下所有科目
        List<Long> SbjIdList = new ArrayList<>();
        for(MajorSubject item : majorSubjectList){
            SbjIdList.add(item.getSubjectId());
        }
        LambdaQueryWrapper<Subject> sbjWrapper = new LambdaQueryWrapper<>();
        sbjWrapper.in(Subject::getId,SbjIdList);
        //科目集合
        List<Subject> subjects = subjectService.getBaseMapper().selectList(sbjWrapper);

        //当前学生所在租户的学年学期集合
        LambdaQueryWrapper<TermTime> termTimeWrapper = new LambdaQueryWrapper<>();
        termTimeWrapper.eq(TermTime::getTenantId,studentInfo.getTenantId());
        List<TermTime> termTimeList = termTimeDao.selectList(termTimeWrapper);

        List<Long> planList = examScoreMapper.getStudentHasTakedExam(studentId);
        for(Long planId : planList){
            Map<String, Object> data = new HashMap<>();
            ExamPlan plan = examPlanService.getExamPlanById(String.valueOf(planId));
            data.put("examName",plan.getExamName());

            if(termTimeList == null || termTimeList.size() <= 0){
                data.put("termTime",null);
            }
            for(TermTime termTime : termTimeList){
                if(plan.getExamTerm() == termTime.getId()){
                    data.put("termTime",termTime.getRemarks());
                }
            }
            //评语
            LambdaQueryWrapper<ExamComment> commentWrapper = new LambdaQueryWrapper<>();
            commentWrapper.eq(ExamComment::getExamPlanId,planId)
                    .eq(ExamComment::getStudentId,studentId);
            ExamComment examComment = examCommentMapper.selectOne(commentWrapper);
            if(examComment != null){
                data.put("comment",examComment.getComment());
            }else{
                data.put("comment",null);
            }
            //学生分数
            List<Map<String,Object>> scores = new ArrayList<>();
            for(Subject sbj : subjects){
                Map<String,Object> map = new HashMap<>();
                map.put("subjectName",sbj.getSubjName());
                LambdaQueryWrapper<ExamScore> scoreWrapper = new LambdaQueryWrapper<>();
                scoreWrapper.eq(ExamScore::getStudentId,String.valueOf(studentId));
                scoreWrapper.eq(ExamScore::getExamPlanId,String.valueOf(planId));
                scoreWrapper.eq(ExamScore::getSubjectId,String.valueOf(sbj.getId()));
                ExamScore examScore = examScoreMapper.selectOne(scoreWrapper);
                if(examScore != null){
                    map.put("score",examScore.getScore());
                }else {
                    map.put("score",null);
                }
                scores.add(map);
            }
            data.put("scoresList",scores);
            returnList.add(data);
        }
        return returnList;
    }
}
